package com.zr.shortlink.project.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zr.shortlink.project.common.convention.exception.ServiceException;
import com.zr.shortlink.project.dao.entity.ShortLinkDO;
import com.zr.shortlink.project.dao.mapper.ShortLinkMapper;
import com.zr.shortlink.project.dto.req.ShortLinkCreateReqDTO;
import com.zr.shortlink.project.dto.resp.ShortLinkCreateRespDTO;
import com.zr.shortlink.project.service.ShortLinkService;
import com.zr.shortlink.project.toolkit.HashUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;


/**
 * 短链接接口实现层
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ShortLinkServiceImpl extends ServiceImpl<ShortLinkMapper, ShortLinkDO> implements ShortLinkService {

    private final RBloomFilter<String> shortUriCreateCachePenetrationBloomFilter;



    public ShortLinkCreateRespDTO createShortLink(ShortLinkCreateReqDTO requestparam) {
        String shortLinkSuffix = generateSuffix(requestparam);
        String fullShortUri = requestparam.getDomain() + "/" + shortLinkSuffix;
        ShortLinkDO shortLinkDO = BeanUtil.toBean(requestparam, ShortLinkDO.class);
        shortLinkDO.setShortUri(shortLinkSuffix);
        shortLinkDO.setEnableStatus(0);
        shortLinkDO.setFullShortUrl(requestparam.getDomain() + "/" + shortLinkSuffix);
        try {
            baseMapper.insert(shortLinkDO);
        } catch (DuplicateKeyException ex) {
            //TODO 已经误判的短链接如何处理
            LambdaQueryWrapper<ShortLinkDO> queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class).eq(ShortLinkDO::getFullShortUrl, fullShortUri);
            ShortLinkDO HasshortLinkDO = baseMapper.selectOne(queryWrapper);
            if(HasshortLinkDO != null){
                log.warn("短链接：{}重复入库",fullShortUri);
                throw new ServiceException("短链接重复入库");

            }
            //第一种，短链接确实存在缓存中
            //第二种，短链接不一定存在缓存中

        }
        shortUriCreateCachePenetrationBloomFilter.add(shortLinkSuffix);
        return ShortLinkCreateRespDTO.builder()
                .fullShortUrl(shortLinkDO.getFullShortUrl())
                .originUrl(shortLinkDO.getOriginUrl())
                .gid(requestparam.getGid())
                .build();

    }


    public String generateSuffix(ShortLinkCreateReqDTO requestparam) {
        int customGenerateCount = 0;
        String shortUri;
        while (true) {
            if(customGenerateCount > 10){
                throw new RuntimeException("短链接生成失败");
            }
            String originUrl = requestparam.getOriginUrl();
            originUrl += System.currentTimeMillis();
            shortUri = HashUtil.hashToBase62(originUrl);
            if (shortUriCreateCachePenetrationBloomFilter.contains(requestparam.getDomain() + "/" +shortUri)) {
                    customGenerateCount++;
                    continue;
            }
            break;
        }
        return shortUri;

    }
}
